Module connections
    Public Sub acceptConnections()
        While True
            Dim client As TcpClient
            log.write("Listening for clients")
            client = serverSocket.AcceptTcpClient
            clients.newClient(client)
            log.write("New client connected and threaded")
        End While
    End Sub

    Public Sub handleClient()
        Dim net As New ernNetwork.Server(clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).connection)
        Dim ip As Net.IPEndPoint = clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).connection.Client.RemoteEndPoint
        Dim msg As protocol
        Dim data As sqlClient.computerDetails
        Dim strings() As String
        Dim heartbeatCount As Integer 'when this is 15 send a heartbeat message
        Dim checkinData As String

        log.write("Waiting for handshake from new client")
        If net.handshake() Then
            log.write("Client successfully shook my hand")
        Else
            log.write("ERROR: Client failed the handshake, so disconnecting and aborting thread")
            clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).connection.Close()
            Threading.Thread.CurrentThread.Abort()
        End If

        'wait for the clients name
        msg.type = protocolType.BLANK
        msg.message = ""
        net.getMessage(msg)
        checkinData = msg.message
        msg.message = Split(msg.message, "::")(0)

        clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).computerName = msg.message
        clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).ip = ip.Address.ToString
        clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).guid = Split(checkinData, "::")(21)
        clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).clientVersion = Split(checkinData, "::")(23)
        log.write("Client checking in: " & msg.message)

        If sql.newClient(clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).guid) Then
            'create a new entry
            log.write("New client - bring them into the fold and make an event log entry")
            clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).guid = sql.addClient(msg.message, ip.Address.ToString, checkinData)
            sql.addToEventLog(sqlClient.eventLogType.i_NewClient, sqlClient.eventLogComponets.serverClientThread, "New client checked in and was added: " & msg.message & " (" & ip.Address.ToString & ")")
            clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).policy = sql.getPolicyDetails(0)
            data.clientVersion = clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).clientVersion
        Else
            data = sql.getClientInformation(clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).guid)
            'mark last checkin time
            clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).policy = sql.getPolicyDetails(data.groupID)
            log.write("The client is an existing client - just update the last checkin time, IP, and return the policy for the client.")
            sql.clientCheckIn(clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).guid, msg.message, ip.Address.ToString, checkinData)
        End If

        msg.message = clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).guid & "::" & data.clientVersion
        msg.type = protocolType.S_checkInOK
        net.sendMessage(msg)
        net.getMessage(msg)

        'pack the policy into a null seperated string
        ReDim strings(14)
        strings(0) = clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).policy.id
        strings(1) = clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).policy.name
        strings(2) = clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).policy.checkInTime
        strings(3) = clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).policy.rebootPolicy.everyFewMinutes
        strings(4) = clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).policy.rebootPolicy.time1
        strings(5) = clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).policy.rebootPolicy.useTime1
        strings(6) = clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).policy.rebootPolicy.time2
        strings(7) = clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).policy.rebootPolicy.useTime2
        strings(8) = clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).policy.rebootPolicy.time3
        strings(9) = clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).policy.rebootPolicy.useTime3
        strings(10) = clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).policy.rebootPolicy.rebootSchedule
        strings(11) = clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).policy.rebootPolicy.scheduledRebootDay
        strings(12) = clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).policy.auPolicy.enabled
        strings(13) = clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).policy.auPolicy.day
        strings(14) = clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).policy.auPolicy.time
        msg.message = Join(strings, ControlChars.NullChar)
        'send the policy to the client.
        msg.type = protocolType.S_policy
        net.sendMessage(msg)
        log.write("Policy for client has been sent!")

        log.write("Determining if they need to reboot because of the day...")
        If clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).policy.rebootPolicy.scheduledRebootDay = Now.Subtract(TimeSpan.FromSeconds(Split(checkinData, "::")(22))).DayOfWeek + 1 Then
            If (Now - Now.Subtract(TimeSpan.FromSeconds(Split(checkinData, "::")(22)))).TotalDays >= 1 Then
                'tell them to reboot
                remindClientToReboot(clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())), net)
                log.write("they NEED to reboot!")
            Else
                log.write("they do NOT need to reboot!")
            End If
        ElseIf (Now - Now.Subtract(TimeSpan.FromSeconds(Split(checkinData, "::")(22)))).TotalDays >= 7 Then
            If clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).policy.rebootPolicy.scheduledRebootDay > 0 Then
                'tell them to reboot
                remindClientToReboot(clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())), net)
                log.write("they NEED to reboot!")
            Else
                log.write("they do NOT need to reboot!")
            End If
        Else
            log.write("they do NOT need to reboot!")
        End If

        log.write("Determining if they need to reboot...")
        If data.rebootFlag <> 0 Then
            If (Date.FromBinary(data.rebootFlag).Add(TimeSpan.FromSeconds(Split(checkinData, "::")(22)))) >= Now Then
                'bastards!  They didnt reboot!
                markClientToReboot(clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())), net)
                log.write("they NEED to reboot!")
            Else
                'clear the reboot flag!
                sql.clearClientRebootFlag(clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).guid)
                log.write("they do NOT need to reboot!")
            End If
        End If
        log.write("They do NOT need to reboot!")

        'start the heartbeat out at 0
        heartbeatCount = 0
        'main loop
        While True
            msg.message = ""
            msg.type = protocolType.BLANK

            If Not clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).inConversation Then
                'clients = clients
                If heartbeatCount = 15 Then
                    'send heartbeat
                    clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).inConversation = True
                    msg.type = protocolType.S_heartbeat
                    msg.message = "ping"
                    'net.sendMessage(msg)
                    'net.getMessage(msg)
                    'MsgBox(msg.message)
                    clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).inConversation = False
                End If
                heartbeatCount = (heartbeatCount + 1) Mod 16
                If net.hasData Then
                    clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).inConversation = True
                    net.getMessage(msg)
                    handleMessage(msg, clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())), net)
                    clients.clients(clients.getIndexByHash(Threading.Thread.CurrentThread.GetHashCode())).inConversation = False
                End If
            End If
            Threading.Thread.Sleep(1000)
        End While
    End Sub

    Public Sub markClientToReboot(ByRef client As ERN_Server.ernClients, ByRef net As ernNetwork.server)
        Dim msg As protocol

        sql.setClientRebootFlag(client.guid)
        msg.type = protocolType.S_rebootReminder
        msg.message = "Your computer needs to be restarted.  Please do as now or as soon as possible.  Thank you!"
        net.sendMessage(msg)
        net.getMessage(msg)
    End Sub

    Public Sub remindClientToReboot(ByRef client As ERN_Server.ernClients, ByRef net As ernNetwork.server)
        Dim msg As protocol

        msg.type = protocolType.S_scheduledRebootReminder
        msg.message = "Don't forget, you're computer should be restarted.  Please do so as soon as possible."
        net.sendMessage(msg)
        net.getMessage(msg)
    End Sub

    Public Sub handleMessage(ByVal msg As protocol, ByRef c As ERN_Server.ernClients, ByRef net As ernNetwork.server)
        Dim strings() As String = Nothing

        If msg.type = protocolType.C_checkIn Then
            'checkRebootStatus(c, net)
            sql.handleScheduledActions(c, net)
            'If c.oldComputerName <> Nothing Then
            'sql.clientCheckIn(c.oldComputerName, c.ip, msg.message)
            'Else
            sql.clientCheckIn(c.guid, c.computerName, c.ip, msg.message)
            'End If
            msg.type = protocolType.S_checkIn
            c.policy = sql.getPolicyDetails(sql.getClientInformation(c.guid).groupID)

            'check for update to the ERN client
            strings = sql.checkForAU(c)
            If Not strings(0) Is Nothing Then
                msg.type = protocolType.S_sendAU
                msg.message = strings(3) & "::" & strings(5) & "::" & strings(6) & "::" & strings(0)
                net.sendMessage(msg)
                net.getMessage(msg)
                'MsgBox(strings(3) & "::" & strings(5) & "::" & strings(6))
                If msg.type = protocolType.C_downloadAU Then
                    net.sendFile(filesLocationAutoUpdate & strings(3))
                End If
            End If

            'pack the policy into a null seperated string
            ReDim strings(14)
            strings(0) = c.policy.id
            strings(1) = c.policy.name
            strings(2) = c.policy.checkInTime
            strings(3) = c.policy.rebootPolicy.everyFewMinutes
            strings(4) = c.policy.rebootPolicy.time1
            strings(5) = c.policy.rebootPolicy.useTime1
            strings(6) = c.policy.rebootPolicy.time2
            strings(7) = c.policy.rebootPolicy.useTime2
            strings(8) = c.policy.rebootPolicy.time3
            strings(9) = c.policy.rebootPolicy.useTime3
            strings(10) = c.policy.rebootPolicy.rebootSchedule
            strings(11) = c.policy.rebootPolicy.scheduledRebootDay
            strings(12) = c.policy.auPolicy.enabled
            strings(13) = c.policy.auPolicy.day
            strings(14) = c.policy.auPolicy.time
            msg.message = Join(strings, ControlChars.NullChar)
            'send the policy to the client.
            msg.type = protocolType.S_policy
            net.sendMessage(msg)
            log.write("Policy for client has been sent!")
        ElseIf msg.type = protocolType.C_clientUpdated Then
            strings = Split(msg.message, "::")
            sql.clientUpdateInstalled(strings(3), c.guid, strings(1), strings(4), strings(5))
        End If
    End Sub
End Module
